// 从redux里导出三个方法
// creageStaore 用于创建store库、
// applyMiddleware 将promise,thunk,saga等中间件应用到我们的store中
// compose 增强我们的store库
// combineReducers 用于将多个reducer函数合并成一个函数
import { createStore, applyMiddleware } from 'redux'
// 中间件，使我们的dispatch能够识别并处理action.payload中的promise方法
import promise from 'redux-promise'
// 中间件，使我们的dispatch能够识别并处理action.payload中的函数
import thunk from 'redux-thunk'
// redux开发者工具 window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
import { composeWithDevTools } from 'redux-devtools-extension'

// 我们自己写的reduce, 经过redux.combineReducers方法合并完成的reducer对象
import reducer from './index'

// 用于持久化我们的reducer的方法，它返回的也是一个reducer对象
import { persistReducer } from 'redux-persist'
// import storageSession from 'redux-persist/lib/storage/session'

import storage from 'redux-persist/lib/storage'

const rootPersistConfig = {
  key: 'root',
  storage: storage,
}
// 使用thunk提供的全局变量注入方法
const Thunk = thunk.withExtraArgument({ a: 1, b: 2 })

// 面试造火箭，上班拧螺丝

// 这里是一个函数，丢给applyMiddleware的时候会被执行
const log = (ref: any) => {
  const { dispatch, getState } = ref
  // 这个是中间件本身， applymiddleware执行后将它注册到中间件队列中
  // 中间件在被store调用时，会接收一个参数，这个参数是下一个处理程序或者是dispatch
  return (next: any) => {
    // 这个是被store调用后返回的方法，它会操作当前的action
    return (action: any) => {
      // 解构
      const { type, payload } = action
      // 打印
      // console.log(`dispatch派发了一个${type}类型，传入的payload是`, payload)
      // 将action丢给下一个处理函数
      next(action)
    }
  }
}

// 创建store库
// createStore接受两个参数，参数一是一个reducer函数，用于处理数据
// 参数二是对redux的增强，compose或者applyMiddleware都是用于增强redux的方法
export default createStore(
  // persistReducer方法，返回一个reducer对象
  // 这个用的也是属于观察者模式，当redux被调用时，会通知persist将当前的修改内容写入到storage里
  persistReducer(rootPersistConfig, reducer),
  // 构成并增强我们的store库的方法，它接受我们使用applyMiddleware生成的函数(
  // 这个函数执行后返回一个store对象树，它里面包含有dispatch\getstate和一些其
  // 它的方法) ，总的来说，这里是createStore方法的第二个参数，它最终应该是一个store对象
  composeWithDevTools(applyMiddleware(promise, Thunk, log))
)
// 数据持久化时，不只是需要持久化reducer,还需要对整个的store进行一次持久化操作
// 抛出
// export default store;

// redux的配置文件做了哪些事情：

// 1. 从redux中导出createStore（克瑞特丝多瑞）和applyMiddleware（奥普莱米德威尔）两个方法，用于创建store和应用中间件
// 2. 导入redux - promise和redux - thunk两个中间件，分别用于处理promise和函数
// 3. 导入persistReducer（坡瑞塞丝特瑞丢色）和presistStore用于持久化我们的reducer和store
// 4. 设定持久化参数presist（坡瑞塞丝特）Config（看飞格），使用storage来存储我们的数据
// 5. 使用createStore和persistConfig来创建我们的store对象
// 6. 导出store对象和经过persistStore持久化后的store对象

// devTools 属于额外的工具，不需在主要的配置过程中描述
